#ifndef LOGGER_H

#include <QObject>
#include <QMap>
#include <QMutex>
#include <functional>
#include "baseappender.h"

// 前置声明Appender子类（根据实际情况补充）
class ConsoleAppender;
class FileAppender;
class TcpAppender;
class UdpAppender;
class QTextEditAppender;
class QPlainTextEditAppender;




// Appender配置参数（不同子类的参数通过QVariantMap传递）
using AppenderParams = QVariantMap;

// Appender元信息：保存配置，不随启用/禁用变化
struct AppenderMeta {
    QString name;               // 唯一名称
    AppenderType type;          // 子类类型
    AppenderParams params;      // 配置参数（如文件路径、IP端口等）
    LogLevel level;             // 日志级别
    bool enabled;               // 是否启用（仅记录状态，不直接控制实例）
};


// 工厂函数：根据参数创建Appender实例（返回BaseAppender*）
using AppenderCreator  = std::function<BaseAppender*(const AppenderParams&, LogLevel)>;


class AppenderFactory  : public QObject
{
    Q_OBJECT
    Q_DISABLE_COPY_MOVE(AppenderFactory )
public:
    static AppenderFactory * instance();

    void startRedirect();// 安装Qt日志重定向
    void stopRedirect();//卸载Qt日志重定向

    void registerCreator(AppenderType type, AppenderCreator  factory);  // 注册Appender子类的创建函数

    bool addAppender(const QString& name,
                     AppenderType type,
                     const AppenderParams& params,
                     LogLevel level = LogLevel::Debug);                 //添加Appender配置（仅保存元信息，不创建实例）


    void setAppenderEnabled(const QString& name, bool enabled);         //启用/禁用Appender（启用时创建实例，禁用时销毁）
    void setAppenderEnabled(AppenderType type , bool enabled);          //启用/禁用Appender（启用时创建实例，禁用时销毁）
    bool isAppenderEnabled(const QString& name);                        //判断Appender是否使能

    void setAppenderLevel(const QString& name,LogLevel level);          //设置Appender的日志等级
    void setAppenderLevel(AppenderType type,LogLevel level);            //设置Appender的日志等级
    void setActiveAppenderLevel(LogLevel level);                        //设置已活跃的Appender的日志等级
    void setAllLogLevel(LogLevel level);                                // 统一设置所有Appender的日志级别（仅更新元信息，实例下次启用时生效）

    // 获取活跃的Appender实例（仅返回已启用的）
    template <typename T>
    T* getActiveAppender(const QString& name) {
        QMutexLocker locker(&m_mutex);
        BaseAppender* base = m_activeAppenders.value(name, nullptr);
        return dynamic_cast<T*>(base); // 转换为子类指针
    }

    // 获取活跃的Appender实例（仅返回已启用的）
    template <typename T>
    T* getActiveAppender(AppenderType type) {
        QString name = getAppenderName(type);
        return getActiveAppender<T>(name);
    }

    void log(LogLevel level, const QString& msg);                       // 输出日志（仅调用活跃实例）

    static void qtMessageHandler(QtMsgType type,
                                 const QMessageLogContext& context,
                                 const QString& msg);                   // Qt日志重定向

    QList<QString> getAllAppenders();                                   //获取所有appeners(名称)
    QList<AppenderType> getAllAppenderType();                           //获取所有appeners(枚举)
    QList<QString> getActiveAppenders();                                //获取活跃的appenders(名称)
    QList<AppenderType> getActiveAppenderType();                        //获取活跃的appenders(枚举)
    QString getAppenderName(AppenderType type);                         //根据枚举获取名称
private:
    explicit AppenderFactory (QObject *parent = nullptr);               //构造函数
    ~AppenderFactory () override;                                       //析构函数

    BaseAppender* createAppender(const AppenderMeta& meta);             //根据元信息创建实例（内部使用）

    static LogLevel qtTypeToLogLevel(QtMsgType type);                   //将Qt消息类型转换为LogLevel
    static QString logLevelToString(LogLevel level);                    //日志级别转字符串（如Debug→"Debug"）

private:
    static AppenderFactory * m_instance;
    mutable QMutex m_mutex;

    QMap<QString, AppenderMeta> m_metaMap;                              //所有Appender的元信息（配置+状态）,只能用来查询和初始化,初始化后不能用来控制
    QMap<QString, BaseAppender*> m_activeAppenders;                     //当前启用的Appender实例（活跃列表）
    QMap<AppenderType, AppenderCreator> m_factories;                    //工厂映射：类型 -> 创建函数
};



#endif // LOGGER_H
